<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\cost\pull;

use app\enum\CommonEnum;
use app\enum\KuaiShouEnum;
use app\enum\ServiceCostEnum;
use app\model\KsMaterialDailyReportModel;
use app\model\KsMaterialPicDailyReportModel;
use app\model\TaskAccountModel;
use app\service\BaseService;
use app\service\client\AccountService;
use app\service\cost\TaskNoticeService;
use app\service\kuaishou\FinanceService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

class KsService extends BaseService implements PullInterface
{
    private array $params = [];

    /**
     * @var bool|mixed|string
     */
    private array $response = [];

    private array $thisResponseData = [];

    private array $responseData = [];

    /**
     * @return bool 请求数据是否为空
     */
    public function isResponseEmpty(): bool
    {
        return empty($this->thisResponseData);
    }

    /**
     * 获取返回码.
     * @return mixed
     */
    public function getResponseCode()
    {
        return $this->response['code'] ?? '-10000';
    }

    /**
     * 获取返回错误信息.
     * @return mixed
     */
    public function getResponseMsg()
    {
        return $this->response['message'] ?? '';
    }

    /**
     * 获取返回体.
     */
    public function getResponseData(array $args = []): array
    {
        return $this->responseData;
    }

    /**
     * 判断服务.
     */
    public function isResponseSuccess(): bool
    {
        // 素材报表无返回状态，只有total_count 和details
        if (isset($this->response['code'])) {
            return FinanceService::isResponseSuccess($this->getResponseCode());
        }
        return isset($this->response['total_count']);
    }

    /**
     * 获取请求头部.
     * @return array|bool
     */
    public function getHeader(string $token = '')
    {
        return FinanceService::getHeader($token);
    }

    /**
     * 获取媒体.
     */
    public function getMediaId(): int
    {
        return CommonEnum::KS_MEDIA;
    }

    /**
     * 获取账户流水.
     * @param TaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAdvertiserDailyFlow(TaskAccountModel $model): bool
    {
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }
        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }
        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'] ?? $model->getAttr('advertiser_id'),
            'start_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'end_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => KuaiShouEnum::MAX_PAGE_SIZE,
        ];
        $this->response = FinanceService::getAdvertiserDailyFlows($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }
        $this->thisResponseData = filterData($this->response['data'], 'details');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }

    /**
     * 获取素材报表.
     * @param TaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMaterialDailyReport(TaskAccountModel $model): bool
    {
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }
        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }

        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'] ?? $model->getAttr('advertiser_id'),
            'start_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'end_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'view_type' => KsMaterialDailyReportModel::VIEW_VIDEO,   // 5视频
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => KuaiShouEnum::MAX_MATERIAL_PAGE_SIZE,
        ];
        $this->response = FinanceService::getMaterialDailyReport($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }
        $this->thisResponseData = filterData($this->response, 'details');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }

    /**
     * 获取图片素材报表.
     * @param TaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMaterialPicDailyReport(TaskAccountModel $model): bool
    {
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'));
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }
        $headers = $this->getHeader($token);
        if (! $headers) {
            return false;
        }

        $this->params = [
            'advertiser_id' => $this->params['advertiser_id'] ?? $model->getAttr('advertiser_id'),
            'start_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'end_date' => $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date')))),
            'view_type' => KsMaterialPicDailyReportModel::VIEW_PIC,   // 16图片
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => KuaiShouEnum::MAX_MATERIAL_PAGE_SIZE,
        ];
        $this->response = FinanceService::getMaterialDailyReport($headers, $this->params) ?? [];
        if (! $this->response) {
            return self::setError('请求有误');
        }
        $this->thisResponseData = filterData($this->response, 'details');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        // 判断是否最后一页，并且存在数据，有则处理图片数据
        if ($this->isResponseEmpty() && $this->responseData) {
            // 先处理数据，一天返回的一个图片数据可能有多条
            $this->responseData = $this->filterPicData($this->responseData);
        }
        return true;
    }

    /**
     * 处理图片报表数据.
     * @param array $responseData 返回体
     */
    private function filterPicData(array $responseData = []): array
    {
        $datas = [];
        $data = [];
        foreach ($responseData as $li) {
            if (! isset($li['pic_signature'])) {
                continue;
            }
            if (! isset($datas[$li['pic_id'] . '_' . $li['stat_date']])) {
                $datas[$li['pic_id'] . '_' . $li['stat_date']]['pic_id'] = $li['pic_id'];
                $datas[$li['pic_id'] . '_' . $li['stat_date']]['pic_signature'] = $li['pic_signature'];
                $datas[$li['pic_id'] . '_' . $li['stat_date']]['stat_date'] = $li['stat_date'];
                $datas[$li['pic_id'] . '_' . $li['stat_date']]['charge'] = $li['charge'];
            } else {
                $datas[$li['pic_id'] . '_' . $li['stat_date']]['charge'] += $li['charge'];
            }
        }
        foreach ($datas as $item) {
            $data[] = $item;
        }
        return $data;
    }
}
